#ifndef TASKS_H
#define TASKS_H

#include "list.h"
#include "nodebuf.h"



// 任务(task)和定时器(timer)管理系统。
// 任务有延迟启动属性，支持在未来某个时间点执行；如果未设定延迟启动，该任务将被尽快调度执行。
// 通过任务处理函数`task_fn`的返回值r，可以设定其r毫秒之后再次执行（实现timer机制）。
// 任务处理函数返回0表示任务已经终结，不会被再次执行。
// 此任务管理器要求使用者不断地调用`tasks_schedule()`以便驱动各任务按预期行为执行。
// by liigo 20200218, 20201030.

struct tasks_t {
    //LIST_HEAD(tasks);
    struct nodebuf_t taskbuf;
    uint8_t needfree;
    struct list_head tasks;
};

// 任务处理函数的参数，参见`task_fn`
// 硬编码任务参数类型是比较遗憾的，理想方案是让使用者定制参数类型。
struct task_args_t {
    int i1, i2, i3;
};

// 任务处理函数，用在执行此任务内各项工作。
// 如果返回值n>0，表示此任务将在n毫秒后再次执行。
// 如果返回值n=0，表示此任务已终结，不会再次执行。
typedef int task_fn(struct task_args_t* args);

struct task_t {
    struct list_head list; // 用作把任务串联为双向链表，要求是首成员
    task_fn *fn; // 返回值n大于0表示n毫秒后再次执行此任务（详见`task_fn`）
    struct task_args_t args; // 任务执行参数，执行时传入task_fn
    uint64_t time_ms; // 预定执行时间点，以毫秒为单位的时间戳，可为0
};

// 初始化任务管理器
// 内部预分配内存空间(malloc)，可存储约ntask个任务；预分配空间用完后按需逐任务申请内存(malloc)。
void tasks_init(struct tasks_t *tasks, int ntask);

// 初始化任务管理器
// 内部使用由调用者提供的预分配内存空间；预分配空间用完后按需逐任务申请内存(malloc)。
void tasks_init_withbuf(struct tasks_t *tasks, void *buf, int buflen);

// 析构任务管理器
void task_fini(struct tasks_t *tasks);

// 往任务管理器中添加一个任务，任务由函数fn及其参数指定
// `delay_ms > 0`表示延迟指定毫秒后执行
// 如无延迟，任务将按照加入顺序被执行，即先加入先执行、后加入后执行。
void tasks_add_task(struct tasks_t *tasks, 
                    int delay_ms, task_fn *fn, int i1, int i2, int i3);

// 从任务管理器中删除任务，通过比较任务函数指针进行匹配
// 如果参数once非0，删除最早加入的第一个匹配任务；如果once为0，删除所有匹配任务；
// 返回被删除的任务个数。
int tasks_remove_task(struct tasks_t *tasks, task_fn *fn, int once);

// 调度任务管理器驱动各任务按预期行为执行
// 使用者应当足够频繁的循环调用此函数，以确保任务管理器正常运作
void tasks_schedule(struct tasks_t *tasks, int64_t now_ms);

// 往控制台窗口输出当前所有任务及其属性
void tasks_print_all(struct tasks_t *tasks, int64_t now_ms, const char *name);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // TASKS_H
